﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Data;

namespace SimpleEntry
{
	/// <summary>
	/// Basic class to implement IDataElement. 
	/// </summary>
	public class DataElement : IDataElement
	{
		// Construct with an object and a given element name
		public DataElement(object o, String name) { Value = o; Name = name; }

		// Construct with a no name. Fakes a name from the .NET type
		public DataElement(object o) { Value = o; Name = String.Format("{0} Data", o.GetType()); }

		public object Value { get; set; }
		public String Name { get; set; }

		/// <summary>
		/// Helper method to general use to wrap double test of
		/// </summary>
		/// <param name="o">The object to test</param>
		/// <param name="includeStringEmptyTest">true to perform a zero length string test. false otherwise</param>
		/// <returns></returns>
		public static bool IsObjectNull(object o, bool includeStringEmptyTest)
		{
			if (o == null) return true;
			if (o.GetType() == typeof(System.DBNull)) return true;
			if (includeStringEmptyTest)
				if (o.ToString().Length == 0) return true;
			return false;
		}

	}

	// Class to leverage the column information from a data table 
	/// <summary>
	/// Implmentation of IDataElement for a cell in a DataRow. It mainly wraps the cell
	/// itself but also implements a method of using the DataColumn properties to store a
	/// User-friendly name for the element in place of the DataColumn column name
	/// Possibly superceded by the class UniversalConverter.
	/// </summary>
	public class DataRowElement : IDataElement
	{
		// IDataElemewnt Interface
		public String Name { get { return m_Name; } set { m_Name = value; } }
		public object Value { get { return m_Dr[this.m_Column]; } set { m_Dr[this.m_Column] = value; } }
		/// <summary>
		/// Create a new instance from a DataRow and colimn number
		/// </summary>
		/// <param name="dr">A DataRow from a DataTable</param>
		/// <param name="columnNo">The column number containing the data.</param>
		public DataRowElement(DataRow dr, int columnNo)
		{
			this.m_Dr = dr;
			this.m_Column = columnNo;
			ExtractMetaData(dr, columnNo);
		}

		// The data element name is by default the column name of the DataTable
		// unless this has been overriden 
		private void ExtractMetaData(DataRow dr, int columnNo)
		{
			// get name
			DataTable dt = dr.Table; ;
			DataColumn dc = dt.Columns[columnNo];
			this.m_DataType = dc.DataType;

			if (dc.ExtendedProperties.ContainsKey(NAME_KEY))
				this.m_Name = dc.ExtendedProperties[NAME_KEY].ToString();
			else
				this.m_Name = dc.ColumnName; //
		}

		/// <summary>
		/// Method to associate a friendly name with a DataColumn that will be 
		/// detected and used by the class. The Friendly name can be used for error 
		/// messages, form labels, search and report field lists etc.
		/// </summary>
		/// <param name="dc">DataColumn to set</param>
		/// <param name="name">Friendly name </param>
		public static void SetName(DataColumn dc, String name) { dc.ExtendedProperties.Add(NAME_KEY, name); }

		public const String NAME_KEY = "NAME";

		DataRow m_Dr;
		int m_Column;
		String m_Name;
		Type m_DataType;
	}
}
